A common method of selectively performing operations in a computer system is to use conditional jumps to skip over sections of code. A conditional jump instruction examines some predetermined state to determine whether the instructions immediately following it should be executed (the sequential instructions) or if instructions at a target address of the jump instruction should be executed. When the target address of the jump instruction specifies an instruction which is within the sequential path of the jump instruction, the intervening instructions are effectively skipped over if the target address is selected. In the X86 architecture, conditional jump instructions use condition codes to specify what state certain EFLAGS register status bits should be in for the jump to be taken. The EFLAGS status bits are typically set as the result of a previous arithmetic or logical instruction.
FIG. 1--Exemplary x86 Instruction
A brief description of the X86 instruction and EFLAGS registers is deemed appropriate. Turning now to FIG. 1, a generic format illustrative of the X86 instruction set is shown. As illustrated, an X86 instruction comprises from one to five optional prefix bytes 2, followed by an operation code (opcode) field 4, an optional addressing mode (MODR/M) byte 6, an optional index-scale-base (SIB) byte 8, an optional displacement field 10 and an optional immediate data field 12.
The opcode field 4 defines the basic operation for a particular instruction. The default operation of a particular opcode may be modified by one or more prefix bytes. For example, a prefix byte may be used to change the address or operand size for an instruction to override the default section used in memory addressing or to instruct the processor to repeat a string operation a number of times. The opcode field 4 follows the prefix bytes 2, if any, and may be one or two bytes in length. Within the opcode field, smaller encoding fields may be defined which may vary according to the class of operation. Such fields may define information such as the direction of the operation, size of displacement, encoding of registers, sign extension and encoding of conditional test fields, as will be discussed in more detail below.
The addressing mode, MODR/M, byte 6 specifies the registers used, as well as memory addressing modes. The scale index base (SIB) byte 8 is used only in 32-bit base relative addressing using scale and index factors. A base field of the SIB byte specifies which register contains the base value for the address calculation and an index field specifies which register contains the index value. A scale field specifies the power of two by which the index value will be multiplied before being added, along with any displacement, to the base value. The next instruction field is the optional displacement field 10, which may be one to four bytes in length. The displacement field 10 contains a constant used in address calculations. The optional immediate field 12, which may also be from one to four bytes in length, contains a constant used as an instruction operand. The shortest X86 instructions are only one byte long and comprise a single opcode byte.
FIG. 2--Exemplary EFLAGS Register
Turning now to FIG. 2, there is illustrated the EFLAGS register of an X86 processor. The EFLAGS register keeps condition codes, mode bits (i.e., status and control flag bits), as well as system flags. The bits within the EFLAGS register are defined in Table 1.
TABLE 1 ______________________________________ Status Flags Auxiliary Carry Flag AF Reports carry or borrow on least significant 4 bits of result Carry Flag CF Reports a carry or borrow from most significant bit Overflow Flag OF Reports a result which is an overflow Parity Flag PF Set to 1 if lowest byte of result has even # of 1 bits Sign Flag SF Set equal to high order bit of result (1 if negative) Zero Flag ZF Cleared to 0 unless result is 0 Control Flag Direction Flag DF Controls direction of string instructions System Flags Alignment Check AC Controls alignment checking ID Flag ID Used to identify the processor Interrupt Enable Flag IF Controls response to interrupts I/O Privilege Level IOPL Controls access to I/O address space Nested Task NT Controls chaining of interrupted task Resume Flag RF Temporarily disables debug faults Trap Flag TF Controls entry into single step mode for debugging Virtual 8086 Mode VM Places processor in virtual 8086 mode Virtual Interrupt Flag VIF "Virtual" image of IF flag Virtual Interrupt VIP Used in virtual 8086 and protected mode Pending Flag ______________________________________
The status flags of the EFLAGS register report the results of arithmetic operations. The status flags are used by the conditional jump instructions to select either the sequential path or the target address path. The sixteen conditions based on the state of the CF, ZF, OF and PF bits of the EFLAGS register that are tested by conventional jump instructions are specified by a four bit condition code as part of the opcodes in the conditional jump instructions. If, for example, the condition code reads 0000, then the jump will occur if there is an overflow. The four bit condition codes of the conditional jump opcodes are set forth in Table 2 below.
TABLE 2 ______________________________________ 0000 O Overflow 0001 NO No overflow 0010 B, NAE Below, Not above/equal 0011 NB, AE Not below, Above/equal 0100 E, Z Equal, Zero 0101 NE, NZ Not equal, Not zero 0110 BE, NA Below equal, Not above 0111 NBE, A Not below equal, Above 1000 S Sign 1001 NS Not sign 1010 P, PE Parity, parity Even 1011 NP, PO Not parity, Parity Odd 1100 L, NGE Less than, Not greater than/equal to 1101 NL, GE Not less than, Greater than/equal to 1110 LE, NG Less than/equal to, Not greater than 1111 NLE, G Not less than/equal to, Greater than ______________________________________
FIG. 3--Conditional Jump
Operation of the condition code conditional jump mechanism described above is illustrated in FIG. 3. Initially, an operation is performed which may cause the EFLAGS status bits or bit to be updated (step 20). Subsequently, a conditional jump instruction is executed. The conditional jump's opcode is read. More particularly, the condition code as described with regard to Table 2 is read (step 22). Next, the appropriate status bit in the EFLAGS register will be read and compared to the condition code set forth in the conditional jump opcode (step 24). If there is a match (step 26), the jump will be activated and the operation at the target address of the jump is executed (step 30). If in step 26 there is no match, the sequential operation is performed (step 28).
Another method for selectively performing operations is to use predicated instructions. Predicated instructions build the condition-checking task into individual instructions such that when they are executed, the operation is performed only if the specified condition is met. If the condition is not met, the operation is canceled, effectively making the instruction a no-op. The primary difference between conditional jumps and predicated instructions is that a conditional jump can instantly cancel a large number of instructions (including instructions which will be refetched and reexecuted). However, predicated instructions self-cancel on a one-by-one basis. In a pipelined processor, conditional jumps cause wasted cycles even with branch prediction if the conditional jump is mispredicted and the target address lies within the sequential path already fetched.
The use of conditional jumps versus predicated instructions is illustrated in Examples 1 and 2. Example 1 illustrates the use of a conditional jump to selectively perform certain operations (applying floor and ceiling functions to the elements of an array and maintaining counts of the number clipped).
______________________________________ clip.sub.-- loop: mov eax, [ebx] ;get array element n cmp eax, MAXVAL ;compare to ceiling value (sets status flags) jle check.sub.-- low ;jump if within range (tests status flags) mov [ebx], MAXVAL ;replace with ceiling value inc esi ;count occurrence of ceiling clipping check.sub.-- low: cmp eax, MINVAL ;compare to floor value jg low.sub.-- ok ;jump if within range mov [ebx], MINVAL ;replace with floor value inc edi ;count occurrence of floor clipping low.sub.-- ok: add ebx, 4 ;increment array index dec ecx ;decrement iteration count jnz clip.sub.-- loop ;loop until entire array is processed ______________________________________